package com.skt.casdemo.util;

import java.io.IOException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.TimeZone;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.location.Address;
import android.location.Geocoder;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.util.Log;

public class ComUtil {

    private static final String TAG = "PAS";
    
	/**
     * Returns Now (millisecond value) 
     * @param 
     * @return long
     */
	public static long getNowMillisecond(){
		Date dt = new Date();		
		return dt.getTime();
	}
	
    /**
     * Returns Today, the start time (millisecond value) 
     * @param 
     * @return long
     */
	public static long getTodayStartmillisecond(){
		Date dt = new Date();
		Date today = new Date(dt.getYear(),dt.getMonth(),dt.getDate());
		return today.getTime();
	}
	
    /**
     * Returns Today, the last time (millisecond value)
     * @param 
     * @return long
     */
	public static long getTodayEndmillisecond(){
		Date dt = new Date();
		Date today = new Date(dt.getYear(),dt.getMonth(),dt.getDate());
		return (today.getTime()+86399999);
	}

    /**
     * Returns NOW Minute
     * @param 
     * @return int
     */
	public static int getMinute(){
		Calendar now = Calendar.getInstance();		
		return now.get(Calendar.MINUTE);
	}

    /**
     * Returns NOW Hour
     * @param 
     * @return int
     */
	public static int getHour(){
		Calendar now = Calendar.getInstance();		
		return now.get(Calendar.HOUR_OF_DAY);
	}
	
	
    /**
     * Returns Today, YYYYMMDD
     * @param 
     * @return String
     */
	public static String getToday(){
		Date dt = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		return sdf.format(dt);
	}

    /**
     * Returns Today, yyyy-MM-dd HH:mm:ss
     * @param 
     * @return String
     */
	public static String getTodayTime(){
		Date dt = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return sdf.format(dt);
	}
    /**
     * Returns Convert milliseconds to yyyy-MM-dd HH:mm:ss
     * @param  long milliseconds
     * @return String
     */
	public static String getConvertDate(long milliseconds){
		Date dt = new Date(milliseconds);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		return sdf.format(dt);
	}

    /**
     * Returns Convert milliseconds to HH:mm:ss
     * @param  long milliseconds
     * @return String
     */
	public static String getConvertTime(long milliseconds){
		Date dt = new Date(milliseconds);
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		
		return sdf.format(dt);
	}	
    /**
     * Returns NetWork Status 
     * @param  ConnectivityManager
     * @return Boolean
     */
	public static boolean checkNeworkStatus(ConnectivityManager cmanager){
		boolean result = false;
		NetworkInfo mobile = cmanager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
		NetworkInfo wifi = cmanager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		NetworkInfo lte_4g = cmanager.getNetworkInfo(ConnectivityManager.TYPE_WIMAX);
		boolean check_lte = false;
		
		if(lte_4g!=null) check_lte = lte_4g.isConnected();
		
		if(mobile.isConnected()||wifi.isConnected()||check_lte) result = true;
		
		return result;
	}
	
	/**
     * Returns Day of the week (code)
     * @param  
     * @return String
     */
	public static String getDayOfWeek(){
		Calendar calendar = Calendar.getInstance();
		int day = calendar.get(calendar.DAY_OF_WEEK);
		
		String weekCode ="";
		
		switch(day){
		case 1 :
			weekCode = "1";
			break;
		case 2 :
			weekCode = "2";
			break;
		case 3 :
			weekCode = "3";
			break;
		case 4 :
			weekCode = "4";
			break;
		case 5 :
			weekCode = "5";
			break;
		case 6 :
			weekCode = "6";
			break;
		case 7 :
			weekCode = "7";
			break;
		}
		
		return weekCode;
	}
	
	/**
     * Returns Distance 단위 킬로미터
     * @param  
     * @return double
     */
	public static double distance(double lat1, double lon1, double lat2, double lon2, char unit) {
	  double theta = lon1 - lon2;
	  double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
	  dist = Math.acos(dist);
	  dist = rad2deg(dist);
	  dist = dist * 60 * 1.1515;
	  dist = dist * 1.609344;
	  return (dist);
	}

	/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
	/*::  This function converts decimal degrees to radians             :*/
	/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
	public static double deg2rad(double deg) {
	  return (deg * Math.PI / 180.0);
	}

	/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
	/*::  This function converts radians to decimal degrees             :*/
	/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
	public static double rad2deg(double rad) {
	  return (rad * 180.0 / Math.PI);
	}
	
	/**
     * Returns 가까운 장소를 반환하거나 맵에 거리를 추가해서 반환할 예정
     * @param  
     * @return double
     */
	public static List<Map<String, String>> nearSpot(List<Map<String, String>> paramList){
		return null;
	}
	
	/**
	 * 
	 * @param context
	 * @param paramList	: 찾을 주소명을 LOCATION_NAME 이란 이름으로 저장하여 던진다.
	 * @return	List<Map<String, String>>
	 * 			해당하는 맵에 정보가 추가되어 나온다.
	 * 			IS_ADDR		: 찾은 주소가 있는지(TRUE/FALSE)
	 * 			FULL_ADDRESS: 전체 주소
	 * 			SIDO_NM		: 시도 명 (날씨의 경우 서버로 던질때 필수값)
	 * 			SGG_NM		: 시군구 명 (날씨의 경우 서버로 던질때 필수값)
	 *          EMD_NM		: 읍면동 명 (날씨의 경우 서버로 던질때 필수값)
	 *          CRDNT_X		: X좌표
	 *          CRDNT_Y		: Y좌표
	 * @throws Exception
	 */
	public static List<Map<String, String>> findAddress(Context context, List<Map<String, String>> paramList) throws Exception{
		List<Map<String, String>> returnList = new ArrayList<Map<String, String>>();
		ListIterator<Map<String, String>> lit = paramList.listIterator();
		Geocoder mGeoCoder = new Geocoder(context);
		
		while(lit.hasNext()){
			Map<String, String> tempMap = lit.next();
			if(tempMap.get("LOCATION_NAME") != null){
				List<Address> addrList = mGeoCoder.getFromLocationName(tempMap.get("LOCATION_NAME"), 1);
				if(addrList.size() != 0){
					//반환받은 Address 가 있다면
					Address address = addrList.get(0);
					String fullAddress = address.getAddressLine(0);
					String adminNm = address.getAdminArea();
					String sidoNm = address.getLocality();
					String emdNm = address.getThoroughfare();
					
					if(adminNm == null){
						int sidoNmLength = sidoNm.length();
						int start = fullAddress.lastIndexOf(sidoNm) + sidoNmLength;
						int end = fullAddress.lastIndexOf(emdNm);
						
						tempMap.put("IS_ADDR", "TRUE");
						tempMap.put("FULL_ADDRESS", fullAddress);
						tempMap.put("SIDO_NM", sidoNm);
						tempMap.put("SGG_NM", fullAddress.substring(start, end-1).trim());
						tempMap.put("EMD_NM", emdNm);
						tempMap.put("CRDNT_X", String.valueOf(address.getLongitude()));
						tempMap.put("CRDNT_Y", String.valueOf(address.getLatitude()));
					}else{
						int adminNmLength = adminNm.length();
						int start = fullAddress.lastIndexOf(adminNm) + adminNmLength;
						int end = fullAddress.lastIndexOf(emdNm);
						
						tempMap.put("IS_ADDR", "TRUE");
						tempMap.put("FULL_ADDRESS", fullAddress);
						tempMap.put("SIDO_NM", adminNm);
						tempMap.put("SGG_NM", fullAddress.substring(start, end-1).trim());
						tempMap.put("EMD_NM", emdNm);
						tempMap.put("CRDNT_X", String.valueOf(address.getLongitude()));
						tempMap.put("CRDNT_Y", String.valueOf(address.getLatitude()));
					}
					returnList.add(tempMap);
				}else{
					//반환받은 Address 가 없다면
					tempMap.put("IS_ADDR", "FALSE");
					returnList.add(tempMap);
				}
			}else{
				//LOCATION_NAME 이 null 이라면
				tempMap.put("IS_ADDR", "FALSE");
				returnList.add(tempMap);
			}
		}
		return returnList;
	}
	/**
	 * 
	 * @param context
	 * @param start_dt	yyyyMMddkkmm 형태의 STRING
	 * @param end_dt	yyyyMMddkkmm 형태의 STRING
	 * @return	List<Map<String, String>>
	 * 			CALENDAR_ID		:캘린더의 ID
	 * 			TITLE			:일정 제목
	 * 			DESCRIPTION		:일정 상세
	 * 			LOCATION_NAME	:일정 장소
	 * 			STATUS			:0 : 확정되지 않음, 1 : 확정됨, 2 : 취소됨
	 * 			START_DT		:일정 시작시간 yyyyMMddkkmm 형태의 String
	 * 			END_DT			:일정 종료시간 yyyyMMddkkmm 형태의 String
	 * 			ALLDAY			:하루종일 걸리는 일정인가 0 : FALSE, 1 : TRUE 
	 * 			DELETED			:삭제된 일정인가 0 : FALSE, 1 : TRUE
	 * @throws Exception 
	 */
	public static List<Map<String, String>> getCalender(Context context, String start_dt, String end_dt) throws Exception{
		List<Map<String, String>> returnList = new ArrayList<Map<String, String>>();
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddkkmm");
		
		Calendar calendar = Calendar.getInstance();
		Date startDate = format.parse(start_dt);
		Date endDate = format.parse(end_dt);
		
		Log.d(TAG, start_dt + " : " + startDate.toLocaleString());
		Log.d(TAG, end_dt + " : " + endDate.toLocaleString());
		
		String[] projection = new String[]{
				"_id",
				"title",
				"eventLocation",
				"eventStatus",
				"description",
				"dtstart",
				"dtend",
				"allDay",
				"deleted"
		};
		Uri uri = Uri.parse("content://com.android.calendar/events");
		
		//
		Cursor cursor = context.getContentResolver().query(
				 uri, projection, "deleted=0 AND (dtstart between "+startDate.getTime()+" AND "+endDate.getTime()+" )",
	             null ,"dtstart asc");
		if(cursor == null || !cursor.moveToFirst()) {
			//시스템에 캘린더가 존재하지 않음(계정이 등록되어 있지 않음)
			return new ArrayList<Map<String, String>>();
		}
		
		Log.d(TAG, "검색결과 : " + String.valueOf(cursor.getCount()));
		
		if(cursor != null){
			if(cursor.moveToFirst()){
				do{
					Map<String, String> tempMap = new HashMap<String, String>();
					
					tempMap.put("CALENDAR_ID"		, cursor.getString(cursor.getColumnIndex("_id")));
					tempMap.put("TITLE"				, cursor.getString(cursor.getColumnIndex("title")));
					tempMap.put("DESCRIPTION"		, cursor.getString(cursor.getColumnIndex("description")));
					tempMap.put("LOCATION_NAME"		, cursor.getString(cursor.getColumnIndex("eventLocation")));
					tempMap.put("STATUS"			, String.valueOf(cursor.getInt(cursor.getColumnIndex("eventStatus"))));
					calendar.setTimeInMillis(cursor.getLong(cursor.getColumnIndex("dtstart")));
					tempMap.put("START_DT"			, format.format(calendar.getTime()));
					calendar.setTimeInMillis(cursor.getLong(cursor.getColumnIndex("dtend")));
					tempMap.put("END_DT"			, format.format(calendar.getTime()));
					tempMap.put("ALLDAY"			, String.valueOf(cursor.getInt(cursor.getColumnIndex("allDay"))));
					tempMap.put("DELETED"			, String.valueOf(cursor.getInt(cursor.getColumnIndex("deleted"))));
					
					returnList.add(tempMap);
				}while(cursor.moveToNext());
			}
		}
		
		cursor.close();
		
		return returnList;
	}
	
	/**
	 * 
	 * @param context
	 * @param param	캘린더 ID : CALENDAR_ID 키값이 있어야 한다.
	 * @return Map<String, String>
	 * CALENDAR_ID		:캘린더의 ID
	 * 			TITLE			:일정 제목
	 * 			DESCRIPTION		:일정 상세
	 * 			LOCATION_NAME	:일정 장소
	 * 			STATUS			:0 : 확정되지 않음, 1 : 확정됨, 2 : 취소됨
	 * 			START_DT		:일정 시작시간 yyyyMMddHHmm 형태의 String
	 * 			END_DT			:일정 종료시간 yyyyMMddHHmm 형태의 String
	 * 			ALLDAY			:하루종일 걸리는 일정인가 0 : FALSE, 1 : TRUE 
	 * 			DELETED			:삭제된 일정인가 0 : FALSE, 1 : TRUE
	 * @return null 
	 *         해당 ID의 캘린더가 존재하지 않음
	 */
	public static Map<String, String> getCalenderById(Context context, Map<String, String> param){
		Map<String, String> returnMap = null;
		
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmm");
		
		final String ID = param.get("CALENDAR_ID");
		
		String[] projection = new String[]{
				"_id",
				"title",
				"eventLocation",
				"eventStatus",
				"description",
				"dtstart",
				"dtend",
				"allDay",
				"deleted"
		};
		
		Uri uri = Uri.parse("content://com.android.calendar/events");
		
		Cursor cursor = context.getContentResolver().query(
				 uri, projection, "deleted=0 AND _id=?",
	             new String[]{ ID } ,null);
		if(cursor == null || !cursor.moveToFirst()) {
			//시스템에 캘린더가 존재하지 않음(계정이 등록되어 있지 않음)
			return new HashMap<String, String>();
		}
		
		if(cursor != null){
			if(cursor.moveToFirst()){
				do{
					returnMap = new HashMap<String, String>();
							
					returnMap.put("CALENDAR_ID"		, cursor.getString(cursor.getColumnIndex("_id")));
					returnMap.put("TITLE"			, cursor.getString(cursor.getColumnIndex("title")));
					returnMap.put("DESCRIPTION"		, cursor.getString(cursor.getColumnIndex("description")));
					returnMap.put("LOCATION_NAME"	, cursor.getString(cursor.getColumnIndex("eventLocation")));
					returnMap.put("STATUS"			, String.valueOf(cursor.getInt(cursor.getColumnIndex("eventStatus"))));
					calendar.setTimeInMillis(cursor.getLong(cursor.getColumnIndex("dtstart")));
					returnMap.put("START_DT"		, format.format(calendar.getTime()));
					calendar.setTimeInMillis(cursor.getLong(cursor.getColumnIndex("dtend")));
					returnMap.put("END_DT"			, format.format(calendar.getTime()));
					returnMap.put("ALLDAY"			, String.valueOf(cursor.getInt(cursor.getColumnIndex("allDay"))));
					returnMap.put("DELETED"			, String.valueOf(cursor.getInt(cursor.getColumnIndex("deleted"))));
				}while(cursor.moveToNext());
			}
		}
		
		cursor.close();
		
		return returnMap;
	}
	
	/**
	 * 오늘과 내일의 시작과 종료를 yyyyMMddHHmm 형태의 String으로 반환한다.
	 * @return Map<String, String>
	 * 			TODAY_START 	: 오늘 시작시간
	 * 			TODAY_END		: 오늘 종료시간
	 * 			TOMORROW_START	: 내일 시작시간
	 * 			TOMORROW_END	: 내일 종료시간
	 */
	public static Map<String, String> getTodayTomorrow(){
		Map<String, String> returnMap = new HashMap<String, String>();
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		
		Date today = new Date();
		Date tomorrow = new Date();
		
		Calendar calendar = Calendar.getInstance();
		
		today = calendar.getTime();
		calendar.add(Calendar.DATE, 1);
		tomorrow = calendar.getTime();
		
		returnMap.put("TODAY_START", format.format(today)+"0000");
		returnMap.put("TODAY_END", format.format(today)+"2359");
		returnMap.put("TOMORROW_START", format.format(tomorrow)+"0000");
		returnMap.put("TOMORROW_END", format.format(tomorrow)+"2359");
		
		return returnMap;
	}
}
